﻿/**
 * Name             :   UserRegistryDb 
 * Namespace        :   HAS.Core.Registry.DataSource
 * Base Classe      :   RegistryDb
 * Type             :   class
 * Author           :   Hamza Saii
 * Creation         :   17/09/2014
 * Updated          :   17/09/2014
 * Licence          :   Public
 * Comment          :   C'est une classe qui hérite de RegistryDb, elle implémente les mêmes
 *                      fonctionnalités a part que cette classe ecrit réellement dans la base 
 *                      de registre HKEY_CURRENT_USER
 * */

namespace HAS.Core.Registry.DataSource
{

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Reflection;

    /// <summary>
    /// Permet l'écriture des paramètres du modèles dans un dossier spécifique 
    /// du HKEY_CURRENT_USER
    /// </summary>
    public class UserRegistryDb : RegistryDb
    {
        /// <summary>
        /// Identifie les paramètres de regsitre à utiliser
        /// </summary>
        private Microsoft.Win32.RegistryKey CurrentReg { get; set; }

        /// <summary>
        /// Le modèle de données
        /// </summary>
        public UserProperty UserProperty { get; set; }

        /// <summary>
        /// Constructeur de la classe
        /// </summary>
        /// <param name="model">un pointeure vers le modèle de données
        /// qui contient les informations à enregistrer</param>
        public UserRegistryDb()
        {
            UserProperty = new DataSource.UserProperty();
            RegistryParamNames = new List<string>();
            //On déclare les évènement
            UserProperty.PropertyChanged += Model_PropertyChanged;
            UserProperty.PropertyChanging += Model_PropertyChanging;
            PropertyInfo[] propertys = UserProperty.GetType().GetProperties();
            // si on a pas de propertys on quitte la fonction
            if (propertys == null)
                return;

            // On boucle sur la liste des propertys
            foreach (PropertyInfo p in propertys)
            {
                RegistryParamNames.Add(p.Name.ToLower());
            }

            //On charge les paramètres depuis la base de registre
            Load();
        }


        /// <summary>
        /// Représente l'action à executer lorsque l'un des property de la liste a changé
        /// </summary>
        /// <param name="sender">L'object déclanchant l'évement</param>
        /// <param name="e">Contient les propriétés d'identification de paramètres qui à changé</param>
        protected void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (RegistryParamNames == null)
                return;

            string paramName = e.PropertyName.ToLower();
            if (RegistryParamNames.Contains(paramName))
            {
                string path = "Software\\" + System.AppDomain.CurrentDomain.FriendlyName + "\\";
                CurrentReg = Microsoft.Win32.Registry.CurrentUser;

                //Naviguer vers le dossier de l'application
                Microsoft.Win32.RegistryKey AppKey = CurrentReg.OpenSubKey(path, true);
                if (AppKey == null)
                {
                    CurrentReg.CreateSubKey(path);
                    AppKey = CurrentReg.OpenSubKey(path, true);
                }

                //Naviguer au classe name
                Microsoft.Win32.RegistryKey ClasseKey = AppKey.OpenSubKey("UserProperty", true);
                if (ClasseKey == null)
                {
                    AppKey.CreateSubKey("UserProperty");
                    ClasseKey = AppKey.OpenSubKey("UserProperty", true);
                }

                string paramValue = UserProperty.GetType().GetProperty(e.PropertyName).GetValue(UserProperty, null).ToString();
                ClasseKey.SetValue(paramName, paramValue,Microsoft.Win32.RegistryValueKind.String);

                ClasseKey.Close();
                AppKey.Close();
                CurrentReg.Close();
            }

        }

        /// <summary>
        /// Permet de charger la liste des paramètres
        /// </summary>
        /// <returns></returns>
        public void Load()
        {
            Microsoft.Win32.RegistryKey ClasseKey = null;
            Microsoft.Win32.RegistryKey AppKey = null;

            //On cherche les propriétés
            PropertyInfo[] propertys = UserProperty.GetType().GetProperties();

            // si on a pas de propertys on quitte la fonction
            if (propertys == null)
                return;
            
            //On initialise les paramètres du registre
            CurrentReg = Microsoft.Win32.Registry.CurrentUser;

            

            // On boucle sur la liste des propertys
            foreach (PropertyInfo p in propertys)
            {
                string path = "Software\\" + System.AppDomain.CurrentDomain.FriendlyName + "\\";


                //Naviguer vers le dossier de l'application
                AppKey = CurrentReg.OpenSubKey(path, true);
                if (AppKey == null)
                {
                    CurrentReg.CreateSubKey(path);
                    AppKey = CurrentReg.OpenSubKey(path, true);
                }

                //Naviguer au classe name
                ClasseKey = AppKey.OpenSubKey("UserProperty", true);
                if (ClasseKey == null)
                {
                    AppKey.CreateSubKey("UserProperty");
                    ClasseKey = AppKey.OpenSubKey("UserProperty", true);
                }

                string paramValue = "";
                if (ClasseKey.GetValue(p.Name.ToLower()) != null)
                    paramValue=  ClasseKey.GetValue(p.Name.ToLower()).ToString();
                p.SetValue(this.UserProperty, paramValue, null);
                
            }

            ClasseKey.Close();
            AppKey.Close();
            CurrentReg.Close();
        }

        /// <summary>
        /// Représente l'action à executer lorsque l'un des property de la liste est en cours de changement
        /// </summary>
        /// <param name="sender">L'object déclanchant l'évement</param>
        /// <param name="e">Contient les propriétés d'identification de paramètres qui à changé</param>
        protected void Model_PropertyChanging(object sender, System.ComponentModel.PropertyChangingEventArgs e)
        {
#if DEBUG
            Debug.WriteLine("Model_PropertyChanging " + e.PropertyName);
#endif
        }
    }
}
